package com.waimai1.waimai.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.waimai1.waimai.common.BaseContext;
import com.waimai1.waimai.common.R;
import com.waimai1.waimai.common.Utils;
//import com.waimai1.waimai.config.PayConfig;
import com.waimai1.waimai.dto.GetCinemaDto;
import com.waimai1.waimai.dto.LockSeatDto;
import com.waimai1.waimai.entity.*;
import com.waimai1.waimai.exception.EnumException;
import com.waimai1.waimai.exception.NotErrorException;
import com.waimai1.waimai.service.*;
//import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
//import io.netty.util.internal.StringUtil;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.PublicKey;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/movie")
@ResponseBody
public class MovieController {
    @Value("${Hw.userNo}")
    private String userNo;
    @Value("${Hw.notifyUrl}")
    private String notifyUrl;
    @Autowired
    public RedisTemplate<String,String> redisTemplate;
    @Autowired
    private HwService hwService;
    @Autowired
    private HwMovieCityService hwMovieCityService;
    @Autowired
    private MyOrderService orderService;
    @Autowired
    private NoticeService noticeService;
    @Autowired
    private CommissionService commissionService;
    @Autowired
    private UserService userService;
    @Autowired
    private BannerService bannerService;
    @Autowired
    private BanCinemaService banCinemaService;
    @Autowired
    private WepayService wepayService;
    @Autowired
    private WepayOrderService wepayOrderService;
    @GetMapping("/getCity")
//    @SuppressWarnings("unchecked")
    public R<Object> getCity() throws JsonProcessingException, UnsupportedEncodingException {
        String time = String.valueOf(new Date().getTime());
        TreeMap<String,Object> argsMap=Utils.getParams("userNo",userNo,"timestamp",time);
        String sign=hwService.getHwSign(argsMap,Utils.HW_MOVIE_CITY);

        Map<String,Object> res=(Map<String, Object>) hwService.getHwData(argsMap,sign,Utils.HW_MOVIE_CITY);
       if(res.get("code").equals(200)){
           hwMovieCityService.updateCity(res);
           return R.success(null);
       }
        return R.success(null);
    }
    @RequestMapping(value={"/getCommission"},method=RequestMethod.GET)
    public R<List<Commission>> getCommission(){
        List<Commission> res=commissionService.list();
        return R.success(res);
    };
    @PostMapping("/getCinema")
    public R<Object> getCinema(@RequestBody GetCinemaDto getCinemaDto) throws UnsupportedEncodingException {
        //如果redis里有信息，则从redis里抓取
        String redisKey="cinemaList:"+getCinemaDto.getCityName()+":"+getCinemaDto.getRegionName();
        String redisKeycity="cityToId:"+getCinemaDto.getCityName()+":"+getCinemaDto.getRegionName();
        String CityRegionId="";
        if(Objects.equals(redisTemplate.hasKey(redisKey),Boolean.TRUE)){
            ArrayList<Map<String,Object>> redisData = JSON.parseObject(redisTemplate.opsForValue().get(redisKey),ArrayList.class);
            return R.success(redisData);
        }
        String time = String.valueOf(new Date().getTime());
        if(Objects.equals(redisTemplate.hasKey(redisKeycity),Boolean.TRUE)){
            CityRegionId=redisTemplate.opsForValue().get(redisKeycity);
        }else{
            QueryWrapper<HwMovieCity> queryWrapper=new QueryWrapper<>();
            queryWrapper.eq("city_region",getCinemaDto.getCityName()+"-"+getCinemaDto.getRegionName());
            HwMovieCity selectCity=hwMovieCityService.getOne(queryWrapper);
            if(null==selectCity){
                throw new NotErrorException(EnumException.NO_FIND_CITY);
            }
            CityRegionId=selectCity.getCityRegionId();
            redisTemplate.opsForValue().set(redisKeycity,selectCity.getCityRegionId());
            redisTemplate.expire(redisKeycity,300, TimeUnit.SECONDS);
        }
        String[] cityRegionId=CityRegionId.split("-");
        TreeMap<String,Object> argsMap=Utils.getParams("userNo",userNo,"cityId",Integer.valueOf(cityRegionId[0]),"regionId",Integer.valueOf(cityRegionId[1]),"timestamp",time);
        String sign=hwService.getHwSign(argsMap,Utils.HW_MOVIE_CINEMA);
        Map<String,Object> res=(Map<String, Object>) hwService.getHwData(argsMap,sign,Utils.HW_MOVIE_CINEMA);
        if(res.get("code").equals(200)){
            //加入黑名单字段
            Object tempData=res.get("data");
            LambdaQueryWrapper<BanCinema> banCinemaLambdaQueryWrapper=new LambdaQueryWrapper<>();
            banCinemaLambdaQueryWrapper.eq(BanCinema::getRegionName,getCinemaDto.getRegionName());
            List<BanCinema> banCinemas= banCinemaService.list(banCinemaLambdaQueryWrapper);
            for(Map<String,Object> i :(List<Map<String,Object>>) tempData){
                i.put("status","上线");
                for(BanCinema j :banCinemas){
                    if(i.get("cinemaID").equals(j.getCinemaId())){
                        i.put("status","下线");
                    }
                }
            }
            //写入缓存
            String resData=JSON.toJSONString(tempData);
            redisTemplate.opsForValue().set(redisKey,resData);
            redisTemplate.expire(redisKey,300, TimeUnit.SECONDS);
            return R.success(tempData);
        }
        throw new NotErrorException((Integer) res.get("code"),res.get("message").toString());
    }
    @PostMapping("/banCinema")
    public R<String> banCinema(@RequestBody Map<String,Object> map){
        LambdaQueryWrapper<BanCinema> banCinemaLambdaQueryWrapper=new LambdaQueryWrapper<>();
        banCinemaLambdaQueryWrapper.eq(BanCinema::getCinemaId,map.get("cinemaId"));
        if("上线".equals(map.get("status"))){
           if(!banCinemaService.remove(banCinemaLambdaQueryWrapper)){
               throw new NotErrorException(EnumException.NO_DELETE);
           };
        }else if("下线".equals(map.get("status"))){
            BanCinema banCinema=new BanCinema();
            banCinema.setCinemaId((Integer) map.get("cinemaId"));
            banCinema.setRegionName((String) map.get("regionName"));
            if(!banCinemaService.save(banCinema)){
                throw new NotErrorException(EnumException.NO_SAVE);
            };
        }
        return R.success("ok");
    }
    @GetMapping("/getFilm")
    public R<Object> getFilm() throws UnsupportedEncodingException {
        //如果redis里有信息，则从redis里抓取
        if(Objects.equals(redisTemplate.hasKey("movieList"),Boolean.TRUE)){
            Object redisData = JSON.parseObject((String)JSON.parseObject(redisTemplate.opsForValue().get("movieList"),Object.class),Object.class);

            return R.success(redisData);
        }
        List[] responseData=hwService.getFilmService();
            return R.success(responseData);
    }

//    @GetMapping("/getNotice")
//    public R<Object> getNotice() throws UnsupportedEncodingException {
//        //如果redis里有信息，则从redis里抓取
//        if(Objects.equals(redisTemplate.hasKey("noticeList"),Boolean.TRUE)){
//            Object redisData = JSON.parseObject(redisTemplate.opsForValue().get("noticeList"),Object.class);
//            return R.success(redisData);
//        }
//        List<Notice> notices=noticeService.list();
//        //写入缓存
//        String resData=JSON.toJSONString(notices);
//        redisTemplate.opsForValue().set("noticeList",resData);
//        redisTemplate.expire("noticeList",300, TimeUnit.SECONDS);
//        return R.success(notices);
//    }
//    @GetMapping("/getBanner")
//    public R<Object> getBanner() throws UnsupportedEncodingException {
//        //如果redis里有信息，则从redis里抓取
//        if(Objects.equals(redisTemplate.hasKey("bannerList"),Boolean.TRUE)){
//            Object redisData = JSON.parseObject(redisTemplate.opsForValue().get("bannerList"),Object.class);
//            return R.success(redisData);
//        }
//        List<Banner> banners=bannerService.list();
//        //写入缓存
//        String resData=JSON.toJSONString(banners);
//        redisTemplate.opsForValue().set("bannerList",resData);
//        redisTemplate.expire("bannerList",300, TimeUnit.SECONDS);
//        return R.success(banners);
//    }
    @PostMapping("/getShow")
    public R<Object> getShow(@RequestBody Integer cinemaId) throws UnsupportedEncodingException {
        String redisKey="showList:"+cinemaId.toString();
        if(Objects.equals(redisTemplate.hasKey(redisKey),Boolean.TRUE)){
            Object redisData =JSON.parseObject(redisTemplate.opsForValue().get(redisKey),Object.class);

//            ArrayList<Map<String,Object>> redisData = JSON.parseObject(String.valueOf(JSON.parse(redisTemplate.opsForValue().get(redisKey))),ArrayList.class);
            return R.success(redisData);
        }
        String time = String.valueOf(new Date().getTime());
        //获取三天内的场次
        long endTimeStamp = new Date().getTime()+3600*1000*24*3;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String endTime=sdf.format(new Date(endTimeStamp));
        TreeMap<String,Object> argsMap=Utils.getParams("userNo",userNo,"cinemaId",cinemaId,"time",endTime,"timestamp",time);
        String sign=hwService.getHwSign(argsMap,Utils.HW_MOVIE_SHOW);
        Map<String,Object> res=(Map<String,Object>) hwService.getHwData(argsMap,sign,Utils.HW_MOVIE_SHOW);
        if(res.get("code").equals(200)){
            //给data加上movie name
            if(Objects.equals(redisTemplate.hasKey("movieAndId"),Boolean.FALSE)){
                hwService.getFilmService();
            }
            HashMap<String,List<HashMap>> data=(HashMap<String,List<HashMap>>) res.get("data");
            for(HashMap<String, Object> item: data.get("showInfor")){
                item.put("movieName",redisTemplate.opsForHash().get("movieAndId", Integer.toString((int)item.get("movieId"))));
            }
            //写入缓存
            String resData=JSON.toJSONString(res.get("data"));
            redisTemplate.opsForValue().set(redisKey,resData);
            redisTemplate.expire(redisKey,300, TimeUnit.SECONDS);
            return R.success(res.get("data"));
        }else{
            throw new NotErrorException((Integer) res.get("code"),res.get("message").toString());
        }

    }
    @PostMapping("/getSeat")
    public R<Object> getSeat(@RequestBody String showId) throws UnsupportedEncodingException {
        String time = String.valueOf(new Date().getTime());
        //获取三天内的场次
        TreeMap<String,Object> argsMap=Utils.getParams("userNo",userNo,"showId",showId,"addFlag",1,"timestamp",time);
        String sign=hwService.getHwSign(argsMap,Utils.HW_MOVIE_SEAT);
        Map<String,Object> res=(Map<String,Object>) hwService.getHwData(argsMap,sign,Utils.HW_MOVIE_SEAT);
        if(res.get("code").equals(200)){
            return R.success(res.get("data"));
        }else{
            throw new NotErrorException((Integer) res.get("code"),res.get("message").toString());
        }
    }
    @PostMapping("/lockSeat")
    public R<Object> LockSeat(@RequestBody LockSeatDto lockSeatDto) throws UnsupportedEncodingException {

        String time = String.valueOf(new Date().getTime());
        String tradeNo="DY"+lockSeatDto.getTakePhoneNumber().substring(7)+time;
        String showInfor= JSON.toJSONString(lockSeatDto.getShowInfor());
        TreeMap<String,Object> argsMap=Utils.getParams("userNo",userNo,"showId",lockSeatDto.getShowId(),"showInfor",showInfor,"notifyUrl",notifyUrl,"takePhoneNumber",lockSeatDto.getTakePhoneNumber(),"tradeNo",tradeNo,"addFlag",1,"timestamp",time);
        //处理前把showInfo编码
        String sign=hwService.getHwSign(argsMap,Utils.HW_MOVIE_LOCK_SEAT);
        argsMap.put("showInfor",URLEncoder.encode(showInfor, "UTF-8"));
        Map<String,Object> res=(Map<String,Object>) hwService.getHwData(argsMap,sign,Utils.HW_MOVIE_LOCK_SEAT);
        if(res.get("code").equals(200)){
            Map<String,Object> resData=(Map<String,Object>) res.get("data");
            //创建订单和详情单
            MyOrder movieOrder=new MyOrder();
            movieOrder.setCinemaName(lockSeatDto.getCinemaName());
            movieOrder.setMovieName(lockSeatDto.getMovieName());
            movieOrder.setHallName(lockSeatDto.getHallName());
            movieOrder.setSeat(lockSeatDto.getSeat());
            movieOrder.setShowTime(lockSeatDto.getShowTime());
            movieOrder.setTicketNumber(lockSeatDto.getTicketNumber());
            movieOrder.setTakePhone(lockSeatDto.getTakePhone());
            movieOrder.setTotalPrice((Double) resData.get("price"));
            movieOrder.setStatus(Utils.STATUS_WAIT_PAY);
            movieOrder.setOutTradeNo(tradeNo);
            movieOrder.setOpenid(BaseContext.getopenId());
            movieOrder.setImgUrl(lockSeatDto.getImgUrl());
            movieOrder.setHwOrderId((String) resData.get("orderNo"));
            movieOrder.setAcid(BaseContext.getAcid());
            if(orderService.save(movieOrder)){
                //添加延时关单功能
                int delayTime=5*60*1000;
                redisTemplate.opsForZSet().add("cancelOrder",tradeNo,System.currentTimeMillis()+delayTime);
            };
//            手机号和注册的不同，则更新
//            if(!BaseContext.getPhone().equals(lockSeatDto.getTakePhone())){
//                userService.updatePhone(movieOrder);
//            }
            resData.put("time",time);
            resData.put("outTradeNo",tradeNo);
            return R.success(resData);
        }else{
            throw new NotErrorException((Integer) res.get("code"),res.get("message").toString());
        }
    }
//    @PostMapping("/createOrder")
//    public R<Object> createOrder(@RequestBody String orderNo) throws UnsupportedEncodingException {
//        String time = String.valueOf(new Date().getTime());
//        TreeMap<String,Object> argsMap=Utils.getParams("userNo",userNo,"orderNo",orderNo,"timestamp",time);
//        String sign=hwService.getHwSign(argsMap,Utils.HW_MOVIE_CREAT_ORDER);
//        Object res= hwService.getHwData(argsMap,sign,Utils.HW_MOVIE_CREAT_ORDER);
//        return R.success(res);
//    }

}
